#include "maintool.h"
#include "normaltool.h"
#include "securitytool.h"
#include "filetool.h"
#include "deeptool.h"
#include "virmachinetool.h"
#include "emailtool.h"
#include "reporttool.h"
#include "hardtool.h"
#include "filefilter.h"
#include "../CheckInfor/DataBase/keywordlib.h"
#include "../Widget/hardwidget.h"
#include "../CheckInfor/maininfor.h"
#include <iostream>
#include <QSysInfo>
#include <QHostInfo>
#include <QNetworkInterface>

MainTool* MainTool::_instance=nullptr;

MainTool* MainTool::GetInstance(QObject* parent){
    if(MainTool::_instance==nullptr)
        MainTool::_instance=new MainTool(parent);
    return MainTool::_instance;
}

MainTool* MainTool::GetInstance(int tds,QObject* parent){
    if(MainTool::_instance==nullptr)
        MainTool::_instance=new MainTool(tds,parent);
    return MainTool::_instance;
}

MainTool::~MainTool(){

    pool->close();      //关闭线程池
}


MainTool::MainTool(QObject *parent):QObject(parent),_modeltools(int(Yzty::ToolCode::Total)){
    pool=ThreadPool::GetInstance(10);   //默认启动10个线程池
    pool->invoke();
}

MainTool::MainTool(int n,QObject *parent):QObject(parent){
    pool=ThreadPool::GetInstance(n);    //启动线程池，指定线程
    pool->invoke();
}

void MainTool::RunToolFunction(Yzty::MODECODE toolcode,Yzty::MODECODE mcode,Yzty::ITEMCODE tcode){
    switch(Yzty::ToolCode(mcode))
    {
        case Yzty::ToolCode::VirMachine:
            this->VirMachineCheck(toolcode,Yzty::VirMachineToolCode(tcode));
            break;
        case Yzty::ToolCode::Security:
            this->SecurityCheck(toolcode,Yzty::SecurityToolCode(tcode));
            break;
        case Yzty::ToolCode::Report:
            break;
        case Yzty::ToolCode::Normal:
            this->NormalCheck(toolcode,Yzty::NormalToolCode(tcode));
            break;
        case Yzty::ToolCode::Email:
            this->EmailCheck(toolcode,Yzty::EmailToolCode(tcode));
            break;
        case Yzty::ToolCode::File:
            this->FileCheck(toolcode,Yzty::FileToolCode(tcode));
            break;
        case Yzty::ToolCode::Deep:
            this->DeepCheck(toolcode,Yzty::DeepToolCode(tcode));
            break;
        case Yzty::ToolCode::Hard:
            this->HardCheck(toolcode,Yzty::HardToolCode(tcode));
            break;
        default:
            break;
    }
}

//加载状态栏信息
void MainTool::StatusBarInforGetLoading(){
    Yzty::StatusBarInfor infor;

    infor._corporation="长江大学保密公司";

    infor._tel="8888-8888";

    infor._cpu=QSysInfo::buildCpuArchitecture();    //cpu架构

    infor._ostype=QSysInfo::prettyProductName();    //os名称

    infor._levelpc=Yzty::LEVEL;

    QNetworkConfigurationManager msg;

    infor._netflag=msg.isOnline();

    for(QHostAddress& temp:QNetworkInterface::allAddresses()){
        if(temp.protocol()==QAbstractSocket::IPv4Protocol&&temp.toString()!="127.0.0.1"){
                infor._ipaddres=temp.toString();       //获取任意一个ipv4地址
                break;
        }
    }

    infor._user=QHostInfo::localHostName();              //获取用户名

    MainInfor::GetInstance()->SetStatusBarInfor(infor);


}


void MainTool::RunToolFunction(Yzty::MODECODE mcode){
//    this->_modeltools[int(Yzty::ToolCode::Hard)]=HardWidget::ShowTools;
    checkDir();
    if(mcode==int(Yzty::ToolCode::File))
        FileCheck(mcode,Yzty::FileToolCode::FKEY);    //文件特殊处理
    else
        for(auto temp:_modeltools[mcode])               //运行对应模块的对应功能
            RunToolFunction(mcode,temp.first,temp.second);
}

void MainTool::NormalCheck(Yzty::MODECODE toolcode,Yzty::NormalToolCode code){
    std::function<void()> tool=NormalTool::GetInstance()->GetToolFunction(code);
    std::function<void()> warp=[tool,toolcode,code,this](){
        tool();
        emit MainTool::Finish(toolcode,int(Yzty::ToolCode::Normal),int(code));
    };
    pool->commit(warp);     //向线程池提交任务
}

void MainTool::SecurityCheck(Yzty::MODECODE toolcode,Yzty::SecurityToolCode code){
    std::function<void()> tool=SecurityTool::GetInstance()->GetToolFunction(code);
    std::function<void()> warp=[tool,toolcode,code,this](){
        tool();
        emit MainTool::Finish(toolcode,int(Yzty::ToolCode::Security),int(code));
    };
    pool->commit(warp);     //向线程池提交任务
}

void MainTool::FileCheck(Yzty::MODECODE toolcode,Yzty::FileToolCode ){
    /*
     * １.　启动过滤器进行过滤
     * ２.　对每一种类型的文件进行Tool的包装
     * ３.　发送消息通知前台完成百分比
    */
    auto ret=pool->commit(&Yzty::FileFilter::Filter,Yzty::FileFilter::GetInstance());
    ret.get();      //等待过滤完成
    const QMap<Yzty::FileTypeLimit::Type,QFileInfoList>& paths=Yzty::FileFilter::GetInstance()->GetAllSelectAblePahts();

    int total=0;        //计算文件的总数
    for(int i=0;i<63;++i)
    {
        if(paths.count(Yzty::FileTypeLimit::Type(int64_t(1)<<i)))
            total+=paths[Yzty::FileTypeLimit::Type(1<<i)].size();
    }
    int total1=FileFilter::GetInstance()->getAbsfilenumbers();
    std::cout<<"file_totalnum0:"<<total1<<std::endl;
    std::cout<<"file_totalnum: "<<total<<std::endl;

    this->filecnts.store(0);
    FileTool::GetInstance()->SetOption("bkhash",1);
    for(int i=0;i<63;++i)
    {
        if(paths.count(Yzty::FileTypeLimit::Type(int64_t(1)<<i)))
        {
            int n=paths[Yzty::FileTypeLimit::Type(1
                                                    <<i)].size();
            for(int j=0;j<n;++j)
            {
                std::function<void()> f=FileTool::GetInstance()->GetToolFunction(Yzty::FileTypeLimit::Type(int64_t(1)<<i),j);

                std::function<void()> func=[this,toolcode,f,total](){
                    f();
                    this->filecnts++;
                    emit this->FileFinish(toolcode,this->filecnts,total);
                };

                pool->commit(func);
            }
        }
    }

}

void MainTool::DeepCheck(Yzty::MODECODE toolcode,Yzty::DeepToolCode code){
    std::function<void()> tool=DeepTool::GetInstance()->GetToolFunction(code);
    std::function<void()> warp=[tool,code,toolcode,this](){
        tool();
        emit MainTool::Finish(toolcode,int(Yzty::ToolCode::Deep),int(code));
    };
    pool->commit(warp);     //向线程池提交任务
}

void MainTool::VirMachineCheck(Yzty::MODECODE toolcode,Yzty::VirMachineToolCode code){
    std::function<void()> tool=VirmachineTool::GetInstance()->GetToolFunction(code);
    std::function<void()> warp=[tool,code,toolcode,this](){
        tool();
        emit MainTool::Finish(int(toolcode),int(Yzty::ToolCode::VirMachine),int(code));
    };
    pool->commit(warp);     //向线程池提交任务
}

void MainTool::EmailCheck(Yzty::MODECODE toolcode,Yzty::EmailToolCode code){
    std::function<void()> tool=EmailTool::GetInstance()->GetToolFunction(code);
    std::function<void()> warp=[tool,toolcode,code,this](){
        tool();
        emit MainTool::Finish(int(toolcode),int(Yzty::ToolCode::Email),int(code));
    };

    pool->commit(warp);     //向线程池提交任务
}

void MainTool::HardCheck(Yzty::MODECODE toolcode,Yzty::HardToolCode code){
    std::function<void()> tool=Yzty::HardTool::GetInstance()->getToolFunction(Yzty::HardToolCode(code));
    std::function<void()> warp=[tool,toolcode,code,this](){
        tool();
        emit MainTool::Finish(toolcode,int(Yzty::ToolCode::Hard),int(code));
    };
    pool->commit(warp);     //向线程池提交任务
}

void MainTool::SetExeCuteToolCode(Yzty::MODECODE tcode,const QVector<QPair<Yzty::MODECODE,Yzty::ITEMCODE>>& codes){
    this->_modeltools[tcode]=codes;
}

void MainTool::checkDir(){
    QDir dir(QDir::currentPath());
    dir.cd("../");
    if(!dir.exists("cache"))
        dir.mkdir(("cache"));
    dir.cd("./cache");    //目录切换到cache文件夹下
    if(!dir.exists("tempfile"))    //如果tempfile文件夹不存在
        dir.mkdir("tempfile");    //创建文件夹
    if(!dir.exists("tempreport"))
        dir.mkdir("tempreport");
}
